package com.ztf.ai.ticket;

import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.messages.SystemMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.List;

import static com.ztf.ai.ticket.TicketDemandParseService.promptTemplate;

@RestController
@RequestMapping("/ticket")
@Slf4j
public class TicketController {

    private final TicketDemandParseService parseService;

    private final RedisTemplate<String, Object> redisTemplate;

    private final ChatModel chatModel;

    public TicketController(
            TicketDemandParseService parseService,
            RedisTemplate<String, Object> redisTemplate,
            ChatModel chatModel
    ) {
        this.parseService = parseService;
        this.redisTemplate = redisTemplate;
        this.chatModel = chatModel;
    }

    @GetMapping("/chat")
    public Flux<String> chat(@RequestParam String msg) {
        Prompt prompt = new Prompt(List.of(
                new SystemMessage(promptTemplate),
                new UserMessage(msg)
        ));
        return chatModel
                .stream(prompt)
                .mapNotNull(resp -> {
                    AssistantMessage output = resp.getResult().getOutput();
                    return output.getText();
                });

    }

    /**
     * 1. 提交抢票需求
     *
     * @param userDemand 用户口语化需求
     * @param userId     用户ID（需登录态，此处简化为参数）
     * @return 任务ID与初始状态
     */
    @PostMapping("/config")
    public Mono<JSONObject> submitDemand(
            @RequestParam String userDemand,
            @RequestParam String userId
    ) {
        // 解析需求
        TicketTaskDTO taskDTO = parseService.parseDemand(userDemand, userId);
        // 保存任务到Redis，初始状态为“待监控（PENDING）”
        redisTemplate.opsForValue().set("TICKET_TASK_" + taskDTO.getTaskId(), taskDTO);
        redisTemplate.opsForValue().set("TICKET_TASK_STATUS_" + taskDTO.getTaskId(), "PENDING");
        // 返回结果
        return Mono.just(new JSONObject() {{
            put("taskId", taskDTO.getTaskId());
            put("status", "PENDING");
            put("message", "抢票任务已创建，正在监控余票");
            put("taskDetail", taskDTO);
        }});
    }

    /**
     * 2. 查询抢票任务状态
     *
     * @param taskId 任务ID
     * @return 任务状态与日志
     */
    @GetMapping("/status/{taskId}")
    public Mono<JSONObject> getTaskStatus(@PathVariable String taskId) {
        String status = (String) redisTemplate.opsForValue().get("TICKET_TASK_STATUS_" + taskId);
        TicketTaskDTO taskDTO = (TicketTaskDTO) redisTemplate.opsForValue().get("TICKET_TASK_" + taskId);
        // 获取任务日志（最近10条）
        List<Object> logs = redisTemplate.opsForList().range("TICKET_TASK_LOG_" + taskId, -10, -1);
        return Mono.just(new JSONObject() {{
            put("taskId", taskId);
            put("status", status == null ? "NOT_FOUND" : status);
            put("taskDetail", taskDTO);
            put("recentLogs", logs);
        }});
    }

    /**
     * 3. 取消抢票任务
     *
     * @param taskId 任务ID
     * @return 取消结果
     */
    @PostMapping("/cancel/{taskId}")
    public Mono<JSONObject> cancelTask(@PathVariable String taskId) {
        // 更新任务状态为“已取消”
        redisTemplate.opsForValue().set("TICKET_TASK_STATUS_" + taskId, "CANCELED");
        return Mono.just(new JSONObject() {{
            put("taskId", taskId);
            put("status", "CANCELED");
            put("message", "抢票任务已取消");
        }});
    }
}